package org.finmanager.statistics;

import org.finmanager.core.Item;
import org.finmanager.data.CategoryList;
import org.finmanager.data.ItemList;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.AbstractDataset;

import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

/**
 * Created by Kelvin on 13/4/2014.
 */

//enhancing the bar chart
public class CategoryStackedBarChartDataSet extends AbstractDataset implements CategoryDataset {
	//getting the categoryList, itemList to enhance the function in the pie chart
	private CategoryList categoryList;
	private ItemList itemList;

	private Calendar calendar = Calendar.getInstance();

	private List<String> rowKey = Arrays.asList("First Quarter", "Second Quarter", "Third Quarter", "Fourth Quarter");

	public CategoryStackedBarChartDataSet(StatisticsModel statisticsModel) {
		this.itemList = statisticsModel.getItemList();
		this.categoryList = statisticsModel.getCategoryList();
	}

	@Override
	public Comparable getRowKey(int i) {
		return rowKey.get(i);
	}

	@Override
	public int getRowIndex(Comparable comparable) {
		return rowKey.indexOf(comparable);
	}

	@Override
	public List getRowKeys() {
		return rowKey;
	}

	@Override
	public Comparable getColumnKey(int i) {
		return categoryList.getCategory(i);
	}

	@Override
	public int getColumnIndex(Comparable comparable) {
		return categoryList.getList().indexOf(comparable);
	}

	@Override
	public List getColumnKeys() {
		return categoryList.getList();
	}

	@Override
	public Number getValue(Comparable rowKey, Comparable columnKey) {
		return getValue(getRowIndex(rowKey), getColumnIndex(columnKey));
	}

	@Override
	public int getRowCount() {
		return rowKey.size();
	}

	@Override
	public int getColumnCount() {
		return categoryList.getCategoryCount();
	}

	@Override
	public Number getValue(int rowIndex, int columnIndex) {
		Double amount = 0.0;
		for (Item item : itemList.getList()) {
			if (checkItemTimeConstraint(item, rowIndex) && getColumnIndex(item.getCategory()) == columnIndex) {
				amount += item.getAmount();
			}
		}
		return amount;
	}

	private boolean checkItemTimeConstraint(Item item, int quarterIndex) {
		if (item.getYear() == calendar.get(Calendar.YEAR) && item.getMonth() == calendar.get(Calendar.MONTH)) {
			int daysInMonth = item.getDate().getActualMaximum(Calendar.DAY_OF_MONTH);
			return Math.floor(item.getDayOfMonth() * 4 / daysInMonth) == quarterIndex;
		} else {
			return false;
		}

	}

	public void increaseMonth() {
		calendar.add(Calendar.MONTH, 1);
		fireDatasetChanged();
	}

	public void decreaseMonth() {
		calendar.add(Calendar.MONTH, -1);
		fireDatasetChanged();
	}

	public void setCalendar(Calendar calendar) {
		this.calendar = calendar;
		fireDatasetChanged();
	}

	public Calendar getCalendar() {
		return calendar;
	}

	@Override
	public void fireDatasetChanged() {
		super.fireDatasetChanged();
	}
}
